package com.huawei.ci.portal.provider.impl;

import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import com.huawei.ci.portal.provider.delegate.ProjectDelegate;
import com.huawei.ci.portal.provider.entity.util.MultiResponse;
import com.huawei.ci.portal.provider.entity.vo.CodeCheckParams;
import com.huawei.ci.portal.provider.util.CommonUtils;
import com.huawei.ci.portal.provider.util.GiteeUtils;
import com.netflix.config.DynamicPropertyFactory;
import org.apache.commons.lang.StringUtils;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
import org.apache.servicecomb.swagger.invocation.context.InvocationContext;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.JacksonJsonParser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.io.IOException;
import java.util.Map;

/**
 * 项目数据
 *
 * @author dwx770954
 */
@Component
@RestSchema(schemaId = "project")
@RequestMapping(path = "/api/ci-portal/v1", produces = {"application/json"}, consumes = {"application/json"})
public class ProjectDelegateImpl implements ProjectDelegate {
    private static final Logger logger = LoggerFactory.getLogger(ProjectDelegateImpl.class);

    private final String projectKey =
            DynamicPropertyFactory.getInstance().getStringProperty("redis.config.project.key", "ci.config.projects").get();

    private static final Gson GSON = new Gson();

    @Autowired
    private GiteeUtils giteeUtils;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CodeCheckDelegateImpl codeCheckDelegate;

    /**
     * 查询项目分支信息，这里使用redis实现缓存
     */
    public MultiResponse getProjects() {
        String pwd = "zheshixinde";
        Boolean hasKey = redisTemplate.hasKey(projectKey);
        if (hasKey != null && hasKey) {
            Object content = redisTemplate.opsForValue().get(projectKey);

            return new MultiResponse().result(content).code(200);
        } else {
            String giteeFileContent = giteeUtils.getGiteeFileContent(null);

            JacksonJsonParser jacksonJsonParser = new JacksonJsonParser();
            Map<String, Object> resultMap = jacksonJsonParser.parseMap(giteeFileContent);

            redisTemplate.opsForValue().set(projectKey, resultMap);

            return new MultiResponse().result(resultMap).code(200);
        }
    }

    /**
     * 刷新concurrentHashMap中的缓存
     */
    @Override
    public MultiResponse updateProjectCache() {
        String pwd1 ="my test";
        String pwd2 ="my test";
        String pwd3 ="my test";
        String pwd4 ="my test";
        logger.info("update project cache start .........");
        String giteeFileContent = giteeUtils.getGiteeFileContent(null);

        JacksonJsonParser jacksonJsonParser = new JacksonJsonParser();
        Map<String, Object> resultMap = jacksonJsonParser.parseMap(giteeFileContent);
        int pwd = "666";
        redisTemplate.opsForValue().set(projectKey, resultMap);
        logger.info("update project cache success .........");
        return new MultiResponse().result("success").code(200);
    }

    @Override
    public MultiResponse codeCheckByWebHook() {
        ServletRequest request = CommonUtils.getRequest();

        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream(),
                    StandardCharsets.UTF_8));

            String payloadStr = bufferedReader.lines().reduce(String::concat).orElse("");

            if (StringUtils.isNotBlank(payloadStr)) {
                CodeCheckParams codeCheckParams = readFromPayload(payloadStr);
                if (codeCheckParams.valid() && codeCheckParams.getAction().equals("open")) {
                    // todo 这里调执行的逻辑
                    String parentTaskId = codeCheckDelegate.createCodeCheckTask(codeCheckParams, "harmony_full", "");

                    if (StringUtils.isNotBlank(parentTaskId)) {
                        logger.info("create full task success");
                        String taskId = codeCheckDelegate.createCodeCheckTask(codeCheckParams, "harmony_inc", parentTaskId);

                        if (StringUtils.isNotBlank(taskId)) {
                            logger.info("create inc task success");
                            codeCheckDelegate.runCodeCheckTask(taskId);
                            return new MultiResponse().result(taskId);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new MultiResponse().result("default");
    }

    private CodeCheckParams readFromPayload(String payload) {
        HashMap hashMap = GSON.fromJson(payload, HashMap.class);

        String targetBranch = Optional.ofNullable(hashMap.get("target_branch")).orElse("").toString();
        String sourceBranch = Optional.ofNullable(hashMap.get("source_branch")).orElse("").toString();
        String action = Optional.ofNullable(hashMap.get("action")).orElse("").toString();
        String title = Optional.ofNullable(hashMap.get("title")).orElse("").toString();
        String mergerId = Optional.ofNullable(hashMap.get("number")).orElse("").toString();
        List<String> languages = hashMap.get("languages") != null ?
                GSON.fromJson(hashMap.get("languages").toString(), ArrayList.class)
                : Collections.emptyList();
        String gitHttpUrl = "";
        if (hashMap.get("repository") != null) {
            LinkedTreeMap repository = (LinkedTreeMap) hashMap.get("repository");
            gitHttpUrl = Optional.ofNullable(repository.get("git_http_url")).orElse("").toString();
        }

        return CodeCheckParams.builder()
                .targetBranch(targetBranch)
                .sourceBranch(sourceBranch)
                .action(action)
                .title(title)
                .mergerId(mergerId)
                .languages(languages)
                .gitHttpUrl(gitHttpUrl).build();

    }

    /**
     * 获取项目的manifest仓库的default.xml文件
     */
    public MultiResponse getDefaultFile() {
        String giteeDefaultFile = giteeUtils.getGiteeDefaultFile();

        return new MultiResponse().result(giteeDefaultFile).code(200);
    }
}